(defpackage :test-abtab
  (:use :common-lisp :lisp-unit :abtab :krb-util))

(in-package :test-abtab)

(define-test test-conditions
  (assert-true (make-condition 'duplicate-driver-registered))
  (assert-true (make-condition 'duplicate-driver-registered :text "foo")))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; driver tests

;; need test for get-constructor-fn that asserts it returns a function...
(define-test test-get-constructor-fn
  (assert-equal 'function (type-of (get-constructor-fn "memory"))))

(defclass dummy-driver (abtab-driver) ())

(define-test test-dummy-driver
  (let ((drv (make-instance 'dummy-driver)))
    (assert-error 'error (write-record drv #()))
    (assert-error 'error (initialize-destination drv '()))
    (assert-error 'error (close-resource drv))))

(define-test test-reregister-driver
  (let ((*registered-drivers* (make-hash-table :test #'equal)))
    (register-driver "test" 'test #'(lambda (&rest args)
				      t))
    (assert-true (driver-registered-p "test"))
    (assert-true (get-driver-info-for-scheme "test"))
    (assert-error 'duplicate-driver-registered
		  (register-driver "test" 'test #'(lambda (&rest args)
						    t)))
    (unregister-driver "test")
    (assert-false (driver-registered-p "test"))
    (assert-error 'driver-not-found-for-scheme
		  (get-driver-info-for-scheme "test"))))

(define-test test-clear-registered-drivers
  (let ((*registered-drivers* (make-hash-table :test #'equal)))
    (register-driver "test" 'test #'(lambda (&rest args)
				      t))
    (assert-true (get-driver-info-for-scheme "test"))
    (clear-registered-drivers)
    (assert-equal 0 (hash-table-count *registered-drivers*))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; the in-memory driver is packaged with the module
(define-test test-mem-driver
  (let* ((uri "memory://test-arena")
	 (drv (open-resource uri))
	 (rec1 '(1 "a" "b"))
	 (rec2 '(2 "c" "d")))
    (initialize-destination drv '("ID" "COL1" "COL2"))
    (assert-true (open-resource uri))
    (write-record drv rec1)
    (write-record drv rec2)
    (reset-for-reading drv)
    (assert-equal rec1 (->list (read-next-record drv)))
    (assert-equal rec2 (->list (read-next-record drv)))
    (assert-false (read-next-record drv))))

(define-test test-initialize-destination-mem
  (let ((drv (open-resource "memory://foo"))
	(cols '("ID" "COL1" "COL2")))
    (initialize-destination drv cols)
    (assert-equal cols (columns drv))
    (assert-equal "ID" (index->column drv 0))
    (assert-equal 0 (column->index drv (nth 0 cols)))
    (assert-equal 1 (column->index drv (nth 1 cols)))
    (assert-equal 2 (column->index drv (nth 2 cols)))))


(define-test test-driver-option
  (let ((drv (make-instance 'abtab-memory-driver:abtab-memory-driver
			    :options (list :foo 1 :bar 2))))
    (assert-equal 1 (driver-option drv :foo))
    (assert-equal 2 (driver-option drv :bar))
    (assert-error 'missing-assoc-entry (driver-option drv :qux))))


;; driver tests
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; macro tests

(define-test test-with-io-from-uri
  (let ((uri "memory://foo"))
    (with-output-to-uri
	(outp uri '("C1" "C2" "C3"))
      (write-record outp #(1 2 3))
      (write-record outp #(4 5 6)))
    (with-input-from-uri
	(inp "memory://foo")
      (assert-equal '(1 2 3) (->list (read-next-record inp)))
      (assert-equal '(4 5 6) (->list (read-next-record inp))))))

;; macro tests
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun exec-tests (&optional quiet)
  "Runs the unit tests, optionally shadowing *error-output* so that
warnings (expected in some cases by the assert-error forms) do not
pollute the screen or log."
  (cond (quiet
	 (with-output-to-string (out)
	   (let ((*error-output* out))
	     (lisp-unit:run-all-tests :test-abtab))))
	(t
	 (lisp-unit:run-all-tests :test-abtab))))

;; (exec-tests t)
;; (use-debugger t)
;; (exec-tests)
;; (remove-all-tests nil)

;; (clear-registered-drivers)

